import React, { Component } from 'react';
import ReactDOM from 'react-dom';


/**
 * React 元素渲染 - 重构的代码版本
 * @date 2020-11-21
 */

/**
 * 作为程序执行的参数
 */
class RenderRestructureFlag extends React.Component {
    static FLAG_NEW_RENDER = 0
    static FLAG_NEW_TICK = 1
}

/**
 * 新的React 元素渲染
 * @returns 返回的是一个jsx对象
 */
function sampleNewRender() {
    return <h1>Hello,wold!</h1>
}

/**
 * 定时器内容
 */
function sampleTickElment() {
    return (
        <div>
            <h1>Hello,world!</h1>
            <h2>现在是{new Date().toLocaleTimeString()}.</h2>
        </div>
    );
}

/**
 * 对展示的部分进行封装
 * @param {日期类} props 
 */
function Clock(props) {
    return (
        <div>
            <h1>Hello,My First Clock!</h1>
            <h2>现在是 {props.date.toLocaleTimeString()}.</h2>
        </div>
    );
}


/**
 * 宝宝闹钟
 * 这里是创建了一个React.Component的ES6类，该类封装了要展示的元素,
 *  值得注意的是在render()方法中，需要使用this.props替换props
 */
class BabyClock extends React.Component {
    render() {
        return (
            <div>
                <h1>Hello,world!</h1>
                <h2>现在是{this.props.date.toLocaleTimeString()}.</h2>
            </div>
        );
    }
}

/** -------------------------综合示例---------------------------- */
/**
 * 1. 使用 ES6 类写法，用 this.props.属性名 来取值。
 * 2. 可以多层 props 来传值，在 ReactDOM.render 定义属性值，传给调用方法 App，
 *    再在调用的ES6类调用中用 props.属性直接赋值过去。
 */

// css样式定义
var myStyle = { color: 'red', textAlign: 'center' }

/**
 * 站点名称组件
 */
class NameComponent extends React.Component {
    render() {
        // 为组件应用style样式
        return <h1 style={myStyle}>网站名称：{this.props.websiteName}</h1>
    }
}

/**
 * 站点URL组件
 */
class UrlComponent extends React.Component {
    render() {
        return <h1>网站地址:{this.props.url}</h1>
    }
}

/**
 * 昵称URL组件
 */
class NickComponent extends React.Component {
    render() {
        return <h1>用户昵称:{this.props.nickname}</h1>
    }
}

/**
 * 复合控件
 * @param {name,url,nickname}} props 
 */
function CompositeControl(props) {
    return (
        <div>
            {/* 父控件向子控件传参 */}
            <NameComponent websiteName={props.websiteName} />
            <UrlComponent url={props.url} />
            <NickComponent nickname={props.nickname} />
        </div>
    )
}

/**
 * 显示复合组件
 */
function showCompositeControl() {
    return <CompositeControl
        websiteName={"菜鸟教程"}
        url={"https://www.runoob.com/react"}
        nickname={"张教主"} />
}

/** -------------------------综合示例---------------------------- */

/** -------------------------程序执行的选择调用---------------------------- */
function buildComponentUI(flag) {
    switch (flag) {
        case 1:
            return sampleNewRender();
        case 2:
            return showCompositeControl();
    }
}

/**
 * 执行新的渲染
 */
function execNewRender(flag) {
    ReactDOM.render(
        buildComponentUI(flag),
        document.getElementById('container')
    );
}

/**
 * 构建定时器UI
 * @param {标记} flag 
 */
function makeTickUI(flag) {
    console.log("makeTickUI flag = " + flag);
    switch (flag) {
        case 0:
            return sampleTickElment();
        case 1:
            return <Clock date={new Date()} />;
        case 2:
            return <BabyClock date={new Date()} />;
    }
}

/**
 * 执行渲染:JSX/Element
 */
function execNewTickRender(flag) {
    console.log("execNewTickRender flag = ");
    ReactDOM.render(
        makeTickUI(flag),
        document.getElementById('container')
    );
}

/**
 * 执行定时器执行
 */
function execNewTick(flag) {
    console.log("execNewTick flag = " + flag);
    // 无参的时候可以直接使用函数名，有参的时候要写函数+参数
    // setInterval(execNewTickRender, 1000);
    setInterval(execNewTickRender(flag), 1000);
}

/** -------------------------程序执行的选择调用---------------------------- */


/**
 * 测试渲染
 *  重构之后的代码，也是可以使用的
 */
function testNewRenderMain(flag) {
    switch (flag) {
        case RenderRestructureFlag.FLAG_NEW_RENDER:
            // 执行新的渲染
            execNewRender(2);
            break;
        case RenderRestructureFlag.FLAG_NEW_TICK:
            // 执行定时器
            execNewTick(2);
            break;
    }
}

export { RenderRestructureFlag, testNewRenderMain }